package com.qinglei.recoup.longconn.service.impl;

import com.fasterxml.jackson.databind.JsonNode;
import com.qinglei.recoup.common.utils.DateUtil;
import com.qinglei.recoup.common.utils.JsonUtils;
import com.qinglei.recoup.longconn.constant.LongConnConstant;
import com.qinglei.recoup.longconn.entity.*;
import com.qinglei.recoup.longconn.enums.ProtocolVersionEnum;
import com.qinglei.recoup.longconn.service.IotMessageStrategyService;
import com.qinglei.recoup.longconn.service.MessageProcService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.util.Map;

/**
 * 物联网消息处理默认实现
 *
 * @author yujunwei
 * @datetime 2022-03-02 17:07
 */
@Service
@Slf4j
public class IotMessageStrategyServiceImpl implements IotMessageStrategyService {

    @Autowired
    private MessageProcService messageProcService;

    @Override
    public String protocolVersion() {
        return ProtocolVersionEnum.DEFAULT.getVersion();
    }

    @Override
    public void handleMethod(Map<String, Object> map) {
        String sn = map.get("sn").toString();
        String content = map.get("content").toString();
        JsonNode itemsNode = JsonUtils.stringToJson(content).get("items");

        Message message;
        JsonNode proCode = itemsNode.get("proCode");
        if (proCode != null && proCode.get("value").asInt() == LongConnConstant.PROJECT_CODE_FALL_DOWN) {
            message = this.parseFallDownUserData(sn, itemsNode);
        } else {
            message = this.parseHealthCareUserData(sn, itemsNode);
        }
        // log.info("IotMessageStrategyServiceImpl->handle, message:{}", message);
        // 处理用户数据
        messageProcService.procUploadDataMessage(message);
        if (message != null) {
            log.info("into ProtocolVersion 3 handle -> sn:{}", message.getSn());
        }
    }

    /**
     * 解析呼吸心跳用户数据
     *
     * @param sn
     * @param itemsNode
     * @return
     */
    private Message parseHealthCareUserData(String sn, JsonNode itemsNode) {
        UserDataBodyV1 userDataBodyV1 = new UserDataBodyV1();
        userDataBodyV1.setFrameNo(itemsNode.get("frameNo").get("value").asLong());
        userDataBodyV1.setBreathPhaseData(JsonUtils.readIntArray(itemsNode.get("breathPhaseData").get("value")));
        userDataBodyV1.setHeartPhaseData(JsonUtils.readIntArray(itemsNode.get("heartPhaseData").get("value")));
        userDataBodyV1.setBreathBpm(itemsNode.get("breathBpm").get("value").asInt());
        userDataBodyV1.setHeartBpm(itemsNode.get("heartBpm").get("value").asInt());
        userDataBodyV1.setS1(itemsNode.get("s1").get("value").asInt());
        userDataBodyV1.setS2(itemsNode.get("s2").get("value").asInt());
        userDataBodyV1.setUnwrappingPhaseData(JsonUtils.readLongArray(itemsNode.get("unwrappingPhaseData").get("value")));
        userDataBodyV1.setOneDimRangeProfile(JsonUtils.readIntArray(itemsNode.get("oneDimRangeProfile").get("value")));
        userDataBodyV1.setBreathDepth(itemsNode.get("breathDepth").get("value").asInt());
        userDataBodyV1.setRangeDimPowerIndex(itemsNode.get("rangeDimPowerIndex").get("value").asInt());
        userDataBodyV1.setRangeDimPowerPeak(itemsNode.get("rangeDimPowerPeak").get("value").asInt());
        userDataBodyV1.setNoisePower(itemsNode.get("noisePower").get("value").asInt());
        userDataBodyV1.setRangeDimSPWMFiltering(itemsNode.get("rangeDimSPWMFiltering").get("value").asInt());
        userDataBodyV1.setTargetRangeGate(itemsNode.get("targetRangeGate").get("value").asInt());
        userDataBodyV1.setAbnormal(itemsNode.get("abnormal").get("value").asInt());
        userDataBodyV1.setOutBedTime(itemsNode.get("outBedTime").get("value").asInt());
        userDataBodyV1.setReserve(JsonUtils.readIntArray(itemsNode.get("reserve").get("value")));

        Message message = new Message();
        message.setSn(sn);
        message.setProjectCode(LongConnConstant.PROJECT_CODE_BREATH_HEART);
        message.setFuncCode(LongConnConstant.FUNC_UP_USER_DATA);
        message.setBody(userDataBodyV1);
        Instant instant = Instant.ofEpochMilli(itemsNode.get("frameNo").get("time").asLong());
        LocalDateTime time = LocalDateTime.ofInstant(instant, ZoneOffset.of("+8"));
        message.setTimestamp(DateUtil.formatFullTime(time, DateUtil.FULL_TIME_MILLI_BAR_PATTERN));

        return message;
    }

    /**
     * 解析跌倒用户数据
     *
     * @param sn
     * @param itemsNode
     * @return
     */
    private Message parseFallDownUserData(String sn, JsonNode itemsNode) {
        long timeMilli = itemsNode.get("packet").get("time").asLong();
        Instant instant = Instant.ofEpochMilli(timeMilli);
        LocalDateTime time = LocalDateTime.ofInstant(instant, ZoneOffset.of("+8"));
        String fullTime = DateUtil.formatFullTime(time, DateUtil.FULL_TIME_MILLI_BAR_PATTERN);

        FallDownUserDataBody body;
        if (itemsNode.get("alg") != null) {
            body = this.parseFallDownDataBodyV1(itemsNode);
        } else {
            body = this.parseFallDownDataBody(itemsNode);
        }
        body.setTime(fullTime);

        Message message = new Message();
        message.setSn(sn);
        message.setProjectCode(LongConnConstant.PROJECT_CODE_FALL_DOWN);
        message.setFuncCode(LongConnConstant.FUNC_UP_USER_DATA);
        message.setBody(body);
        message.setTimestamp(fullTime);
        message.setDataTime(timeMilli);

        return message;
    }

    /**
     * 解析跌倒数据体（旧版本）
     *
     * @param itemsNode
     * @return
     */
    private FallDownUserDataBody parseFallDownDataBodyV1(JsonNode itemsNode) {
        FallDownUserDataBodyV2 fallDownUserDataBodyV2 = new FallDownUserDataBodyV2();
        fallDownUserDataBodyV2.setPacket(itemsNode.get("packet").get("value").asInt());
        fallDownUserDataBodyV2.setAlg(JsonUtils.readIntArray(itemsNode.get("alg").get("value")));
        fallDownUserDataBodyV2.setSec1(JsonUtils.readIntArray(itemsNode.get("Sec1").get("value")));
        fallDownUserDataBodyV2.setSec2(JsonUtils.readIntArray(itemsNode.get("Sec2").get("value")));
        fallDownUserDataBodyV2.setSec3(JsonUtils.readIntArray(itemsNode.get("Sec3").get("value")));
        fallDownUserDataBodyV2.setSec4(JsonUtils.readIntArray(itemsNode.get("Sec4").get("value")));
        fallDownUserDataBodyV2.setSec5(JsonUtils.readIntArray(itemsNode.get("Sec5").get("value")));
        fallDownUserDataBodyV2.setSec6(JsonUtils.readIntArray(itemsNode.get("Sec6").get("value")));
        fallDownUserDataBodyV2.setSec7(JsonUtils.readIntArray(itemsNode.get("Sec7").get("value")));
        fallDownUserDataBodyV2.setSec8(JsonUtils.readIntArray(itemsNode.get("Sec8").get("value")));
        fallDownUserDataBodyV2.setSec9(JsonUtils.readIntArray(itemsNode.get("Sec9").get("value")));
        fallDownUserDataBodyV2.setSec10(JsonUtils.readIntArray(itemsNode.get("Sec10").get("value")));
        fallDownUserDataBodyV2.setExist(JsonUtils.readIntArray(itemsNode.get("exist").get("value")));
        fallDownUserDataBodyV2.setL1(JsonUtils.readIntArray(itemsNode.get("L1").get("value")));
        fallDownUserDataBodyV2.setL2(JsonUtils.readIntArray(itemsNode.get("L2").get("value")));
        fallDownUserDataBodyV2.setScore(JsonUtils.readIntArray(itemsNode.get("Score").get("value")));
        fallDownUserDataBodyV2.setSWS(JsonUtils.readIntArray(itemsNode.get("SWS").get("value")));
        fallDownUserDataBodyV2.setSPS(JsonUtils.readIntArray(itemsNode.get("SPS").get("value")));
        fallDownUserDataBodyV2.setCW(JsonUtils.readIntArray(itemsNode.get("CW").get("value")));
        fallDownUserDataBodyV2.setRe(JsonUtils.readIntArray(itemsNode.get("Re").get("value")));

        return fallDownUserDataBodyV2;
    }

    /**
     * 解析跌倒数据体（旧版本）
     *
     * @param itemsNode
     * @return
     */
    private FallDownUserDataBody parseFallDownDataBody(JsonNode itemsNode) {
        FallDownUserDataBodyV1 fallDownUserDataBodyV1 = new FallDownUserDataBodyV1();
        fallDownUserDataBodyV1.setPacket(itemsNode.get("packet").get("value").asInt());
        fallDownUserDataBodyV1.setFrame(JsonUtils.readIntArray(itemsNode.get("frame").get("value")));
        fallDownUserDataBodyV1.setDB1(JsonUtils.readIntArray(itemsNode.get("dB1").get("value")));
        fallDownUserDataBodyV1.setDB2(JsonUtils.readIntArray(itemsNode.get("dB2").get("value")));
        fallDownUserDataBodyV1.setDB3(JsonUtils.readIntArray(itemsNode.get("dB3").get("value")));
        fallDownUserDataBodyV1.setDB4(JsonUtils.readIntArray(itemsNode.get("dB4").get("value")));
        fallDownUserDataBodyV1.setDB5(JsonUtils.readIntArray(itemsNode.get("dB5").get("value")));
        fallDownUserDataBodyV1.setExist(JsonUtils.readIntArray(itemsNode.get("exist").get("value")));
        fallDownUserDataBodyV1.setHeight(JsonUtils.readIntArray(itemsNode.get("height").get("value")));
        fallDownUserDataBodyV1.setL1(JsonUtils.readIntArray(itemsNode.get("L1").get("value")));
        fallDownUserDataBodyV1.setL2(JsonUtils.readIntArray(itemsNode.get("L2").get("value")));

        return fallDownUserDataBodyV1;
    }
}
